<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>元素遍历</title>
  </head>
  <body></body>
  <script>
    /*
    1.IE9 之前的版本不会把元素间的空格当成空白节点，而其他浏览器则会。这样就导致了 childNodes和 firstChild 等属性上的差异。为了弥补这个差异，同时不影响
      DOM 规范，W3C 通过新的 Element Traversal 规范定义了一组新属性。
    2.Element Traversal API 为 DOM 元素添加了 5 个属性：
      a.childElementCount，返回子元素数量（不包含文本节点和注释）；
      b.firstElementChild，指向第一个 Element 类型的子元素（Element 版 firstChild）；
      c.lastElementChild，指向最后一个 Element 类型的子元素（Element 版 lastChild）；
      d.previousElementSibling ，指向前一个 Element 类型的同胞元素（ Element 版 previousSibling）；
      e.nextElementSibling，指向后一个 Element 类型的同胞元素（Element 版 nextSibling）。
    3.在支持的浏览器中，所有 DOM 元素都会有这些属性，为遍历 DOM 元素提供便利。这样开发者就不用担心空白文本节点的问题了。
    4.IE9 及以上版本，以及所有现代浏览器都支持 Element Traversal 属性。
   */

    //过去要以跨浏览器方式遍历特定元素的所有子元素
    function checkAccrossBrower() {
      let parentElement = document.getElementById("parent");
      let currentChildNode = parentElement.firstChild;
      // 没有子元素，firstChild 返回 null，跳过循环
      while (currentChildNode) {
        if (currentChildNode.nodeType === 1) {
          // 如果有元素节点，则做相应处理
          processChild(currentChildNode);
        }
        if (currentChildNode === parentElement.lastChild) {
          break;
        }
        currentChildNode = currentChildNode.nextSibling;
      }
    }

    //现在使用 Element Traversal 属性之后，
    function checkElementTraversalAccrossBrower() {
      let parentElement = document.getElementById("parent");
      let currentChildElement = parentElement.firstElementChild;
      // 没有子元素，firstElementChild 返回 null，跳过循环
      while (currentChildElement) {
        // 这就是元素节点，做相应处理
        processChild(currentChildElement);
        // 判断父元素是否只有一个子节点，如果 firstElementChild === lastElementChild，说明首节点与末尾节点为同一个元素节点
        // 进而说明父元素只有一个元素节点，则直接退出循环
        if (currentChildElement === parentElement.lastElementChild) {
          break;
        }
        // 没有退出循环，说明首节点与末尾节点不是同一个节点，则将下一个节点赋值给首节点，继续循环调用 processChild 函数处理首节点。通过此方式，遍历父元素所有的子元素节点。
        currentChildElement = currentChildElement.nextElementSibling;
      }
    }
    function processChild(){}
  </script>
</html>
